﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Text;
using System.Threading.Tasks;
using Abp;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Configuration;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using LeadThing.AbpZeroTemplate.ArticleCategorys.Authorization;
using LeadThing.AbpZeroTemplate.ArticleCategorys.Dtos;
using LeadThing.AbpZeroTemplate.Dto;

namespace LeadThing.AbpZeroTemplate.ArticleCategorys
{
    /// <summary>
    /// 文章类别服务实现
    /// </summary>
    


    public class ArticleCategoryAppService : AbpZeroTemplateAppServiceBase, IArticleCategoryAppService
    {
        private readonly IRepository<ArticleCategory, long> _articleCategoryRepository;
        private readonly IArticleCategoryListExcelExporter _articleCategoryListExcelExporter;


        private readonly ArticleCategoryManage _articleCategoryManage;
        /// <summary>
        /// 构造方法
        /// </summary>
        public ArticleCategoryAppService(IRepository<ArticleCategory, long> articleCategoryRepository,
ArticleCategoryManage articleCategoryManage
      , IArticleCategoryListExcelExporter articleCategoryListExcelExporter
  )
        {
            _articleCategoryRepository = articleCategoryRepository;
            _articleCategoryManage = articleCategoryManage;
            _articleCategoryListExcelExporter = articleCategoryListExcelExporter;
        }


        #region 实体的自定义扩展方法

        private IQueryable<ArticleCategory> _articleCategoryRepositoryAsNoTrack => _articleCategoryRepository.GetAll().AsNoTracking();

        /// <summary>
        /// 获取文章分类
        /// </summary>
        /// <returns></returns>
        public async Task<ListResultDto<ArticleCategoryListDto>> GetArticleCategory()
        {
            var items = await _articleCategoryRepository.GetAll().ToListAsync();

            return new ListResultDto<ArticleCategoryListDto>(
                items.Select(item =>
                {
                    var dto = item.MapTo<ArticleCategoryListDto>();
                    return dto;
                }).ToList());
        }

        /// <summary>
        /// 获取全部地区树形数据
        /// </summary>
        /// <returns></returns>
        public List<ComboboxItemDto> GetArticleCategoryTree()
        {
            var list = GetAllArticleCategorys().Select(p => new ComboboxItemDto(
                 p.Id.ToString(),
                 p.DisplayTitle
                  )).ToList();
            list.Insert(0, new ComboboxItemDto("0", "请选择"));
            return list;
        }

        /// <summary>
        /// 树形排序
        /// </summary>
        /// <returns></returns>
        private List<ArticleCategoryListDto> GetAllArticleCategorys()
        {
            var articleCategorys = _articleCategoryRepository.GetAll().Where(p => p.Level < 3).OrderBy(p => p.Id).ToList();
            var rootArticleCategorys = articleCategorys.Where(p => p.ParentId == 0 && p.Level < 3).OrderBy(p => p.Id);

            var result = new List<ArticleCategoryListDto>();

            foreach (var rootArticleCategory in rootArticleCategorys)
            {
                var level = 0;
                AddArticleCategory(rootArticleCategory, articleCategorys, result, level);
            }

            return result;
        }

        /// <summary>
        /// 递归排序
        /// </summary>
        /// <param name="articleCategory"></param>
        /// <param name="allArticleCategorys"></param>
        /// <param name="result"></param>
        /// <param name="level"></param>
        private void AddArticleCategory(ArticleCategory articleCategory, List<ArticleCategory> allArticleCategorys, List<ArticleCategoryListDto> result, int level)
        {
            var flatArticleCategory = articleCategory.MapTo<ArticleCategoryListDto>();
            flatArticleCategory.Level = level;
            string layers = new string('—', articleCategory.Level);
            flatArticleCategory.DisplayTitle = layers + flatArticleCategory.Title;
            result.Add(flatArticleCategory);

            var child = allArticleCategorys.Where(i => i.ParentId == articleCategory.Id);
            if (child.Count() == 0)
            {
                return;
            }

            var children = allArticleCategorys.Where(p => p.ParentId != 0 && p.ParentId == articleCategory.Id).ToList();

            foreach (var childArea in children)
            {
                AddArticleCategory(childArea, allArticleCategorys, result, level + 1);
            }
        }

        #endregion


        #region 文章类别管理

        /// <summary>
        /// 根据查询条件获取文章类别分页列表
        /// </summary>
        [AbpAuthorize(ArticleCategoryAppPermissions.ArticleCategory)]
        public async Task<PagedResultDto<ArticleCategoryListDto>> GetPagedArticleCategorysAsync(GetArticleCategoryInput input)
        {

            var query = _articleCategoryRepositoryAsNoTrack;
            //TODO:根据传入的参数添加过滤条件

            var articleCategoryCount = await query.CountAsync();

            var articleCategorys = await query
            .OrderBy(input.Sorting)
            .OrderByDescending(p => p.SortId)
            .ToListAsync();

            var articleCategoryListDtos = articleCategorys.MapTo<List<ArticleCategoryListDto>>();
            return new PagedResultDto<ArticleCategoryListDto>(
            articleCategoryCount,
            articleCategoryListDtos
            );
        }

        /// <summary>
        /// 通过Id获取文章类别信息进行编辑或修改 
        /// </summary>
        [AbpAuthorize(ArticleCategoryAppPermissions.ArticleCategory)]
        public async Task<GetArticleCategoryForEditOutput> GetArticleCategoryForEditAsync(NullableIdDto<long> input)
        {
            var output = new GetArticleCategoryForEditOutput();

            ArticleCategoryEditDto articleCategoryEditDto;

            if (input.Id.HasValue)
            {
                var entity = await _articleCategoryRepository.GetAsync(input.Id.Value);
                articleCategoryEditDto = entity.MapTo<ArticleCategoryEditDto>();
            }
            else
            {
                articleCategoryEditDto = new ArticleCategoryEditDto();
            }

            output.ArticleCategory = articleCategoryEditDto;
            return output;
        }


        /// <summary>
        /// 通过指定id获取文章类别ListDto信息
        /// </summary>
        [AbpAuthorize(ArticleCategoryAppPermissions.ArticleCategory)]
        public async Task<ArticleCategoryListDto> GetArticleCategoryByIdAsync(EntityDto<long> input)
        {
            var entity = await _articleCategoryRepository.GetAsync(input.Id);

            return entity.MapTo<ArticleCategoryListDto>();
        }







        /// <summary>
        /// 新增或更改文章类别
        /// </summary>
        [AbpAuthorize(ArticleCategoryAppPermissions.ArticleCategory)]
        public async Task CreateOrUpdateArticleCategoryAsync(CreateOrUpdateArticleCategoryInput input)
        {
            if (input.ArticleCategoryEditDto.Id.HasValue)
            {
                await UpdateArticleCategoryAsync(input.ArticleCategoryEditDto);
            }
            else
            {
                await CreateArticleCategoryAsync(input.ArticleCategoryEditDto);
            }
        }

        /// <summary>
        /// 新增文章类别
        /// </summary>
        [AbpAuthorize(ArticleCategoryAppPermissions.ArticleCategory_CreateArticleCategory)]
        public virtual async Task<ArticleCategoryEditDto> CreateArticleCategoryAsync(ArticleCategoryEditDto input)
        {
            //TODO:新增前的逻辑判断，是否允许新增

            var entity = input.MapTo<ArticleCategory>();

            entity.Id = await _articleCategoryRepository.InsertOrUpdateAndGetIdAsync(entity);
            entity = await _articleCategoryRepository.GetAsync(entity.Id);

            //查询父节点的深度赋值
            if (entity.ParentId > 0)
            {
                var model = _articleCategoryRepository.FirstOrDefault(p => p.Id == entity.ParentId);
                entity.Level = model.Level + 1;
            }
            else
                entity.Level = 1;

            //修改节点列表和深度
            entity = await _articleCategoryRepository.UpdateAsync(entity);

            return entity.MapTo<ArticleCategoryEditDto>();
        }

        /// <summary>
        /// 编辑文章类别
        /// </summary>
        [AbpAuthorize(ArticleCategoryAppPermissions.ArticleCategory_EditArticleCategory)]
        public virtual async Task UpdateArticleCategoryAsync(ArticleCategoryEditDto input)
        {
            //TODO:更新前的逻辑判断，是否允许更新

            var entity = await _articleCategoryRepository.GetAsync(input.Id.Value);
            input.MapTo(entity);

            await _articleCategoryRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 删除文章类别
        /// </summary>
        [AbpAuthorize(ArticleCategoryAppPermissions.ArticleCategory_DeleteArticleCategory)]
        public async Task DeleteArticleCategoryAsync(EntityDto<long> input)
        {
            //TODO:删除前的逻辑判断，是否允许删除
            await _articleCategoryRepository.DeleteAsync(input.Id);
        }

        /// <summary>
        /// 批量删除文章类别
        /// </summary>
        [AbpAuthorize(ArticleCategoryAppPermissions.ArticleCategory_DeleteArticleCategory)]
        public async Task BatchDeleteArticleCategoryAsync(List<long> input)
        {
            //TODO:批量删除前的逻辑判断，是否允许删除
            await _articleCategoryRepository.DeleteAsync(s => input.Contains(s.Id));
        }

        #endregion

        #region 文章类别的Excel导出功能


        public async Task<FileDto> GetArticleCategoryToExcel()
        {
            var entities = await _articleCategoryRepository.GetAll().ToListAsync();

            var dtos = entities.MapTo<List<ArticleCategoryListDto>>();

            var fileDto = _articleCategoryListExcelExporter.ExportArticleCategoryToFile(dtos);



            return fileDto;
        }


        #endregion

    }
}
